home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 22
/
Amiga Format AFCD22 (Jan 1998, Issue 106).iso
/
-in_the_mag-
/
converters
/
graphics
/
netpbm
/
ppmtoinfo
/
ppmtoinfo.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-11-16
|
8KB
|
334 lines
#include <exec/types.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>
#include <proto/all.h>
#include <pragmas/wb_pragmas.h>
#include <pragmas/exec_pragmas.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct {
int colors;
int depth;
int max;
int red[256];
int green[256];
int blue[256];
}
palette;
palette *pal=NULL; /* The palette the icon will use */
char *tool=NULL; /* The default tool of the icon */
char *tooltypes[] = { /* Tool type list. */
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};
#define MAXTOOLTYPES 10
int typecount=0;
USHORT *imageData=NULL;
/* our functions */
void cleanup(char *,int);
BOOL makeIcon(UBYTE *, char **, char *);
int
CXBRK(void)
{
cleanup("User Interrupt.",21);
return (0);
} /* Disable SAS Lattice CTRL/C handling */
struct Image iconImage1 =
{
0, 0, /* Top Corner */
0,0,0, /* Width, Height, Depth */
NULL, /* Image Data */
0x000, 0x000, /* PlanePick,PlaneOnOff */
NULL /* Next Image */
};
struct DiskObject Icon =
{
WB_DISKMAGIC, /* Magic Number */
WB_DISKVERSION, /* Version */
{ /* Embedded Gadget Structure */
NULL, /* Next Gadget Pointer */
0, 0, 0, 0, /* Left,Top,Width,Height */
GADGIMAGE | GADGHBOX, /* Flags */
GADGIMMEDIATE | RELVERIFY, /* Activation Flags */
BOOLGADGET, /* Gadget Type */
&iconImage1, /* Render Image */
NULL, /* Select Image */
NULL, /* Gadget Text */
NULL, /* Mutual Exclude */
NULL, /* Special Info */
0, /* Gadget ID */
NULL /* User Data */
},
WBPROJECT, /* Icon Type */
NULL, /* Default Tool */
NULL, /* Tool Type Array */
NO_ICON_POSITION, /* Current X */
NO_ICON_POSITION, /* Current Y */
NULL, /* Drawer Structure */
NULL, /* Tool Window */
4000 /* Stack Size */
};
/* Opens and allocations we must clean up */
struct Library *IconBase = NULL;
int
log2(int val)
{
int c=0;
while(val/=2) c++;
return c;
}
#define MIN(a,b) ((a)<(b))?(a):(b);
/*
* build palette
*
* This function reads in a ppmfile and coverts it to a "palette".
*
* This function assumes a few things: 1. each color in the ppmfile is
* unique. 2. the ppmfile has no more than 256 pixels. (Longer images
* are truncated.)
*/
palette *
build_palette(char *fname)
{
FILE *ppmfile;
char buf[80];
int wide, high;
int i;
palette *pal;
pal = AllocVec(sizeof(palette), NULL);
if (!pal)
cleanup("Could not allocate palette.",21);
ppmfile = fopen(fname, "r");
if (!ppmfile)
cleanup("Could not open palette file.\n",21);
fgets(buf, 80,ppmfile);
if (strcmp(buf, "P3\n"))
cleanup("Palette must be in P3 format.\n",21);
fscanf(ppmfile, "%d %d", &wide, &high);
pal->colors=MIN(256,wide*high);
pal->depth=log2(pal->colors);
if ((1<<pal->depth)<pal->colors) pal->depth++;
printf("Palette will require %d planes.\n",pal->depth);
if (fscanf(ppmfile,"%d",&pal->max)!=1) cleanup("Failed to read palette file.\n",21);
for(i=0;i<pal->colors;i++)
if (fscanf(ppmfile,"%d",&pal->red[i])!=1)
cleanup("Failed reading the palette file.\n",21);
else if (fscanf(ppmfile,"%d",&pal->green[i])!=1)
cleanup("Failed reading the palette file.\n",21);
else if (fscanf(ppmfile,"%d",&pal->blue[i])!=1)
cleanup("Failed reading the palette file.\n",21);
printf("Palette:\n");
for(i=0;i<pal->colors;i++)
printf("\t%d\t%d\t%d\n",pal->red[i],pal->green[i],pal->blue[i]);
fclose(ppmfile);
return pal;
}
void
scale_palette(palette *p,int m)
{
int i;
for (i=0;i<pal->colors;i++) {
pal->red[i]=(((float)pal->red[i]/(float)p->max)*(float)m+0.5);
pal->green[i]=(((float)pal->green[i]/(float)p->max)*(float)m+0.5);
pal->blue[i]=(((float)pal->blue[i]/(float)p->max)*(float)m+0.5);
}
printf("Scaled Palette:\n");
for(i=0;i<pal->colors;i++)
printf("\t%d\t%d\t%d\n",pal->red[i],pal->green[i],pal->blue[i]);
}
int
lookup_color(palette *pal,int r, int g, int b)
{
int i;
for (i=0;i<pal->colors; i++)
if ((pal->red[i]==r)&&(pal->green[i]==g)&&(pal->blue[i]==b)) return i;
return -1;
}
void
PutPixel(USHORT *imagedata, int wwide, int high, int depth, int x, int y, int c)
{
int windex, bindex, fsize;
int count;
USHORT mask;
windex=(wwide*y)+x/16;
fsize=wwide*high;
bindex=x%16;
mask=1<<(15-bindex);
for (count=0;count<depth;count++) {
if (c&1)
imagedata[windex]|=mask;
c/=2;
windex+=fsize;
}
}
void
build_image(palette *pal, struct Image *image, FILE *ppmfile)
{
int wide, high, max, wwide;
char buf[80];
int x,y,c,r,g,b;
if (!ppmfile)
cleanup("Could not open image file.\n",21);
fgets(buf,80,ppmfile);
if (strcmp(buf,"P6\n"))
cleanup("Image must be in P6 format.\n",21);
fscanf(ppmfile,"%d",&wide);
fscanf(ppmfile,"%d",&high);
if (!fscanf(ppmfile,"%d",&max)) cleanup("Failed to read image file.\n",21);;
if (max!=pal->max) scale_palette(pal,max);
/* skip to the EOL */
while (fgetc(ppmfile)!='\n') {}
image->Width=wide; image->Height=high;
image->Depth=pal->depth;
image->PlanePick=pal->depth-1;
image->PlaneOnOff=pal->depth-1;
wwide=wide/16; if (wwide*16!=wide) wwide++;
imageData=AllocVec(wwide*high*pal->depth*2,MEMF_CLEAR);
if (!imageData) cleanup("Could not allocate memory for the image.\n",21);
image->ImageData=imageData;
for(y=0;y<high;y++)
for(x=0;x<wide;x++) {
r=fgetc(ppmfile); g=fgetc(ppmfile); b=fgetc(ppmfile);
c=lookup_color(pal,r,g,b);
if (c<0) {
fprintf(stderr,"%d %d %d\n",r,g,b);
cleanup("Image contains a color not in the palette.\n",21);
}
PutPixel(imageData,wwide,high, pal->depth,x,y,c);
}
}
#define USAGE "syntax: ppmtoinfo [-tool {default tool}] 0[-tooltype {tool type}]10\n\t-map {mapfile} -icon {infofile} [{ppmfile}]\n"
/*
* ppmtoinfo
*
* Arguments: ppmfile mapfile iconfile
*
* ppmfile - the image to turn into an icon mapfile - a ppmfile which
* describes the palette to use iconfile - the icon to make.
*/
void
main(int argc, char **argv)
{
char *ppmfile=NULL;
char *mapfile=NULL;
char *infofile=NULL;
FILE *In;
int i;
/* parse the arguments */
for (i=1;(i<argc)&&(argv[i][0]=='-');i++) {
if (!strcmp(argv[i],"-tool")) { tool=argv[i+1]; i++; }
else if (!strcmp(argv[i],"-tooltype")) {
if (typecount<MAXTOOLTYPES) {
tooltypes[typecount]=argv[i+1];
i++; typecount++;
}
} else if (!strcmp(argv[i],"-map")) {
mapfile=argv[i+1]; i++;
} else if (!strcmp(argv[i],"-icon")) {
infofile=argv[i+1]; i++;
} else cleanup(USAGE,21);
}
if (i>argc) cleanup(USAGE,21);
if (i<argc) {
ppmfile=argv[i]; i++;
}
if (!mapfile) cleanup(USAGE,21);
if (i<argc) cleanup(USAGE,21);
/* Open icon.library */
if (!(IconBase = OpenLibrary("icon.library", 33)))
cleanup("Could not open icon.library",21);
pal=build_palette(mapfile);
if (ppmfile) In=fopen(ppmfile,"r");
else In=stdin;
build_image(pal,&iconImage1,In);
Icon.do_Gadget.Width=iconImage1.Width;
Icon.do_Gadget.Height=iconImage1.Height;
Icon.do_DefaultTool=tool;
Icon.do_ToolTypes=tooltypes;
PutDiskObject(infofile,&Icon);
cleanup("Finished.",0);
}
void
cleanup(char *s, int n)
{
if (pal) FreeVec(pal);
if (imageData) FreeVec(imageData);
if (IconBase)
CloseLibrary(IconBase);
puts(s);
exit(n);
}